package br.uvv.sao.managedBean;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.component.UIInput;
import javax.faces.context.FacesContext;

import br.uvv.sao.domain.Professor;
import br.uvv.sao.domain.Usuario;
import br.uvv.sao.enums.SituUsuario;
import br.uvv.sao.rn.ProfessorRN;
import br.uvv.sao.util.CriptoHashUtil;
import br.uvv.sao.util.MsgUtil;
import br.uvv.sao.util.Util;

public class ProfessorBean implements Serializable {
	private static final long serialVersionUID = 1L;

	private ProfessorRN professorRN = new ProfessorRN();
	
	private Boolean instancia;
	private String confirmacaoSenha;
	private String campoBuscaNome;
	private String campoBuscaMatricula;
	private Professor professorInstance;
	private Professor professorInstanceTemp;
	private List<Professor> professorList;
	
	//Alteração de Senha
	private String alteracao_senhaAntiga;
	private String alteracao_senhaNova;
	private String alteracao_senhaNovaConfirmacao;
	
	@PostConstruct
	public void init(){
		professorInstance = professorInstanceTemp = new Professor();
		professorList = new ArrayList<Professor>();
		confirmacaoSenha = campoBuscaMatricula = campoBuscaNome = 
		alteracao_senhaAntiga = alteracao_senhaNova = alteracao_senhaNovaConfirmacao = new String();
		instancia = true;
	}
	
	public String professor(){
		init();
		return "goProfessores";
	}
	
	public String goHome(){
		professorInstance = professorInstanceTemp = null;
		professorList = null;
		confirmacaoSenha = campoBuscaMatricula = campoBuscaNome = 
		alteracao_senhaAntiga = alteracao_senhaNova = alteracao_senhaNovaConfirmacao = null;
		instancia = null;
		return "goHome";
	}
	
	public String paginaProfessor(){
		Usuario usuario = Util.getUsuarioLogado();
		if(usuario instanceof Professor){
			professorInstance = (Professor) usuario;
		}else{
			professorInstance = new Professor();
			MsgUtil.msgWarn("É preciso estar logado com um professor para acessar esta funcionalidade.");
			return "goHome";
		}
		return "goPaginaProfessor";
	}
	
	public String goCreate(){
		instancia = false;
		String matricula = professorRN.gerarMatricula();
		professorInstance = new Professor();
		professorInstance.setCodigo(matricula);
		professorInstance.setSituacao(SituUsuario.Ativo);
		return "goCreate";
	}
	
	public String goEdit(){
		professorInstanceTemp = professorInstance;
		instancia = true;
		return "goEdit";
	}
	
	public String selecionarProfessor(){
		professorInstance = professorInstanceTemp;
		professorInstanceTemp = null;
		professorList = new ArrayList<Professor>();
		instancia = false;
		return null;
	}
	
	public String salvar(){
		try {
			if (!professorInstance.getSenha().equals(confirmacaoSenha)&&!instancia){
				MsgUtil.msgError("As senhas informadas são diferentes!");
			} else {
				if(professorRN.salvar(professorInstance)){
					MsgUtil.msgInfo("Professor '" + professorInstance.getNomeCompleto() + "' foi salvo com sucesso!");
					instancia = false;
					return "goShow";
				}else{
					MsgUtil.msgError("Erro ao salvar dados do professor");
					return null;
				}
			}
		}
		catch(Exception e){
			MsgUtil.msgInfo("Ocorreu um erro ao criar o professor '" + professorInstance.getNomeCompleto() + "'!");
		}
		return null;
	}
	
	public String salvarMinhaPagina(){
		try {
			if (!professorInstance.getSenha().equals(confirmacaoSenha)&&!instancia){
				MsgUtil.msgError("As senhas informadas são diferentes!");
			} else {
				if(professorRN.salvar(professorInstance)){
					MsgUtil.msgInfo("Professor '" + professorInstance.getNomeCompleto() + "' foi salvo com sucesso!");
					instancia = false;
					return "goMinhaPagina";
				}else{
					MsgUtil.msgError("Erro ao salvar dados do professor");
					return null;
				}
			}
		}
		catch(Exception e){
			MsgUtil.msgInfo("Ocorreu um erro ao criar o professor '" + professorInstance.getNomeCompleto() + "'!");
		}
		return null;
	}
	
	public String excluir(){
		try {
			/*Verificar se ele pode ser excluido. 
			Implementar isso usando RNException
			*/ 
			professorRN.excluir(professorInstance);
			MsgUtil.msgInfo("Professor '" + professorInstance.getNomeCompleto() + "' foi removido com sucesso!");
			professorInstance = new Professor();
			instancia = true;
		} catch(Exception e){
			MsgUtil.msgInfo("Ocorreu um erro ao remover o professor '" + professorInstance.getNomeCompleto() + "' !");
		}
		return null;
	}
	
	public String ativar(){
		try {
			if (!professorInstance.getSituacao().equals(SituUsuario.Ativo)){
				professorInstance.setSituacao(SituUsuario.Ativo);
				professorRN.salvar(professorInstance);
				MsgUtil.msgInfo("Professor '" + professorInstance.getNomeCompleto() + "' foi ativado com sucesso!");
				instancia = false;
			} else {
				MsgUtil.msgInfo("O Professor '" + professorInstance.getNomeCompleto() + "' já está ativo!");
			}
		} catch(Exception e){
			MsgUtil.msgInfo("Ocorreu um erro ao ativar o professor '" + professorInstance.getNomeCompleto() + "' !");
		}
		return null;
	}
	
	public String desativar(){
		try {
			if (professorInstance.getSituacao().equals(SituUsuario.Ativo)){
				professorInstance.setSituacao(SituUsuario.Desativado);
				professorRN.salvar(professorInstance);
				instancia = false;
				MsgUtil.msgInfo("Professor '" + professorInstance.getNomeCompleto() + "' foi desativado com sucesso!");
			} else {
				MsgUtil.msgInfo("O Professor '" + professorInstance.getNomeCompleto() + "' já está desativado!");
			}
		} catch(Exception e){
			MsgUtil.msgInfo("Ocorreu um erro ao desativar o professor '" + professorInstance.getNomeCompleto() + "' !");
		}
		return null;
	}
	
	public String desistirEdit(){
		professorInstance = professorInstanceTemp;
		professorInstanceTemp = null;
		instancia = true;
		return "goShow";
	}
	
	public String desistirMinhaPaginaEdit(){
		professorInstance = professorInstanceTemp;
		professorInstanceTemp = null;
		instancia = true;
		return "goMinhaPagina";
	}
	
	public String desistir(){
		professorInstance = professorInstanceTemp = null;
		professorList = null;
		confirmacaoSenha = campoBuscaMatricula = campoBuscaNome = 
		alteracao_senhaAntiga = alteracao_senhaNova = alteracao_senhaNovaConfirmacao = null;
		instancia = null;
		return null;
	}
	
	//Fazer ainda os validadores
	public String alterarSenha(){
		if (!professorInstance.getSenha().equals(alteracao_senhaAntiga)){
			MsgUtil.msgError("Sua senha antiga está incorreta!");
		} else{
			if (alteracao_senhaNova.equals(CriptoHashUtil.hashSHA1(alteracao_senhaNovaConfirmacao))){
				professorInstance.setSenha(alteracao_senhaNovaConfirmacao);
				professorRN.salvar(professorInstance);
				MsgUtil.msgInfo("Senha redefinida com sucesso! Um email lhe foi enviado com os novos dados.");
			} else {
				MsgUtil.msgError("A nova senha e sua confirmação são diferentes!");
			}
		}
		return null;
	}
	
	public void filtrarProfessor(){
		professorList = professorRN.listar(campoBuscaNome, campoBuscaMatricula);
	}
	
	public void validateEmail(FacesContext context, UIComponent toValidate, Object value) {  
	    String email = (String) value;
	    Pattern p = Pattern.compile("^[\\w-]+(\\.[\\w-]+)*@([\\w-]+\\.)+[a-zA-Z]{2,7}$");  
	    Matcher m = p.matcher(email);
	    if (!m.find()) {
	    	((UIInput)toValidate).setValid(false);
	    	FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, "O campo 'Email' não contém um email válido!", "");
	    	context.addMessage(toValidate.getClientId(context), message); 
	    	return;
	    }
	    Boolean temElementos = professorRN.verificarEmail(email,professorInstance, instancia);
	    if (!temElementos){
	        ((UIInput)toValidate).setValid(false);
	        FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, "O email informado já existe!", "");  
	        context.addMessage(toValidate.getClientId(context), message);  
	    }  
	}
	
	public void validateNomeCompleto(FacesContext context, UIComponent toValidate, Object value) {  
		String nome = (String) value;
		Boolean temElementos = professorRN.verificarNome(nome,professorInstance, instancia);
	    if (!temElementos){
	        ((UIInput)toValidate).setValid(false);
	        FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Já existe um professor com este nome cadastrado!", "");  
	        context.addMessage(toValidate.getClientId(context), message);  
	    }  
	}
	
	public Professor getProfessorInstance() {
		return professorInstance;
	}
	
	public void setProfessorInstance(Professor professorInstance) {
		this.professorInstance = professorInstance;
	}
	public List<Professor> getProfessorList() {
		return professorList;
	}
	public void setProfessorList(List<Professor> professorList) {
		this.professorList = professorList;
	}
	public Professor getProfessorInstanceTemp() {
		return professorInstanceTemp;
	}
	public void setProfessorInstanceTemp(Professor professorInstanceTemp) {
		this.professorInstanceTemp = professorInstanceTemp;
	}
	public String getCampoBuscaMatricula() {
		return campoBuscaMatricula;
	}
	public String getCampoBuscaNome() {
		return campoBuscaNome;
	}
	public void setCampoBuscaMatricula(String campoBuscaMatricula) {
		this.campoBuscaMatricula = campoBuscaMatricula;
	}
	public void setCampoBuscaNome(String campoBuscaNome) {
		this.campoBuscaNome = campoBuscaNome;
	}
	public String getConfirmacaoSenha() {
		return confirmacaoSenha;
	}
	public void setConfirmacaoSenha(String confirmacaoSenha) {
		this.confirmacaoSenha = CriptoHashUtil.hashSHA1(confirmacaoSenha);  
	}
	public Boolean getInstancia() {
		return instancia;
	}
	public void setInstancia(Boolean instancia) {
		this.instancia = instancia;
	}

	public String getAlteracao_senhaAntiga() {
		return alteracao_senhaAntiga;
	}

	public void setAlteracao_senhaAntiga(String alteracao_senhaAntiga) {
		this.alteracao_senhaAntiga = CriptoHashUtil.hashSHA1(alteracao_senhaAntiga);;
	}

	public String getAlteracao_senhaNova() {
		return alteracao_senhaNova;
	}

	public void setAlteracao_senhaNova(String alteracao_senhaNova) {
		this.alteracao_senhaNova = CriptoHashUtil.hashSHA1(alteracao_senhaNova);
	}

	public String getAlteracao_senhaNovaConfirmacao() {
		return alteracao_senhaNovaConfirmacao;
	}

	public void setAlteracao_senhaNovaConfirmacao(
			String alteracao_senhaNovaConfirmacao) {
		this.alteracao_senhaNovaConfirmacao = alteracao_senhaNovaConfirmacao;
	}
	
}
